<?php

require_once __DIR__ . '/../autoload.php';

use Database\Connection;
use ORM\Model;
use examples\models\User;
use examples\models\Post;
use examples\models\Comment;
use examples\models\Tag;

// 加载数据库配置
$config = require_once __DIR__ . '/../config/database.php';

// 创建数据库连接
$connection = Connection::getInstance($config);

// 设置模型的数据库连接
Model::setConnection($connection);

// 示例1：关系预加载（解决N+1问题）
echo "\n示例1：关系预加载（解决N+1问题）\n";
echo "--------------------------------------\n";

try {
    // 创建测试数据
    $user = User::updateOrCreate(
        ['email' => 'eager@example.com'],
        ['name' => '预加载测试用户', 'password' => 'eager123']
    );
    
    // 为用户创建多篇文章
    for ($i = 1; $i <= 3; $i++) {
        Post::updateOrCreate(
            ['title' => "预加载测试文章{$i}"],
            ['content' => "这是预加载测试文章{$i}的内容", 'user_id' => $user->id]
        );
    }
    
    echo "测试数据创建完成\n";
    
    // 不使用预加载（会导致N+1问题）
    echo "\n不使用预加载:\n";
    $posts = Post::query()
                ->where('title', 'like', '%预加载%')
                ->get();
    
    echo "找到 " . count($posts) . " 篇文章\n";
    
    foreach ($posts as $post) {
        // 每次访问user关系都会执行一次额外的查询
        echo "- {$post->title} (作者: {$post->user->name})\n";
    }
    
    // 使用预加载（解决N+1问题）
    echo "\n使用预加载:\n";
    $relationManager = new \ORM\RelationManager($connection);
    $posts = Post::query()
                ->where('title', 'like', '%预加载%')
                ->get();
    
    // 预加载所有文章的作者关系
    $posts = $relationManager->eagerLoad($posts, 'user');
    
    foreach ($posts as $post) {
        // 不会执行额外的查询，因为关系已预加载
        echo "- {$post->title} (作者: {$post->user->name})\n";
    }
} catch (\Exception $e) {
    echo "关系预加载示例失败: " . $e->getMessage() . "\n";
}

// 示例2：事务处理
echo "\n示例2：事务处理\n";
echo "------------------------\n";

try {
    // 开始事务
    $connection->beginTransaction();
    
    // 创建用户
    $user = User::create([
        'name' => '事务测试用户',
        'email' => 'transaction@example.com',
        'password' => 'trans123'
    ]);
    
    // 创建文章
    $post = Post::create([
        'title' => '事务测试文章',
        'content' => '这是一篇事务测试文章的内容',
        'user_id' => $user->id
    ]);
    
    // 提交事务
    $connection->commit();
    
    echo "事务提交成功，用户ID: {$user->id}, 文章ID: {$post->id}\n";
} catch (\Exception $e) {
    // 回滚事务
    $connection->rollBack();
    echo "事务回滚: " . $e->getMessage() . "\n";
}

// 示例3：复杂查询
echo "\n示例3：复杂查询\n";
echo "------------------------\n";

try {
    // 使用查询构建器进行复杂查询
    $posts = Post::query()
                ->select(['id', 'title', 'created_at'])
                ->where('title', 'like', '%测试%')
                ->orderBy('created_at', 'DESC')
                ->limit(5)
                ->get();
    
    echo "最近的5篇测试文章:\n";
    
    foreach ($posts as $post) {
        echo "- {$post->title} (创建于: {$post->created_at})\n";
    }
    
    // 聚合查询
    $postCount = Post::query()->count();
    echo "\n总文章数: {$postCount}\n";
    
    // 分组查询
    $userPostCounts = Post::query()
                        ->select(['user_id'])
                        ->groupBy('user_id')
                        ->get();
    
    echo "\n每个用户的文章数:\n";
    
    foreach ($userPostCounts as $count) {
        $user = User::find($count->user_id);
        $userPostCount = Post::query()->where('user_id', $count->user_id)->count();
        
        if ($user) {
            echo "- {$user->name}: {$userPostCount} 篇文章\n";
        }
    }
} catch (\Exception $e) {
    echo "复杂查询示例失败: " . $e->getMessage() . "\n";
}

// 示例4：模型关系和多对多关系
echo "\n示例4：模型关系和多对多关系\n";
echo "-------------------------------\n";

try {
    // 创建标签
    $tag1 = Tag::updateOrCreate(['name' => 'PHP'], []);
    $tag2 = Tag::updateOrCreate(['name' => 'ORM'], []);
    $tag3 = Tag::updateOrCreate(['name' => '数据库'], []);
    
    // 获取一篇文章
    $post = Post::query()->first();
    
    if (!$post) {
        $user = User::query()->first();
        
        if (!$user) {
            $user = User::create([
                'name' => '关系测试用户',
                'email' => 'relation_test@example.com',
                'password' => 'relation123'
            ]);
        }
        
        $post = Post::create([
            'title' => '关系测试文章',
            'content' => '这是一篇用于测试多对多关系的文章',
            'user_id' => $user->id
        ]);
    }
    
    echo "文章《{$post->title}》已准备好\n";
    
    // 模拟添加标签（在实际应用中，这通常通过中间表实现）
    echo "为文章添加标签（模拟多对多关系）\n";
    
    // 在实际应用中，这里应该是向中间表插入记录
    // 但由于我们没有实际的数据库，所以只是模拟这个过程
    echo "- 添加标签: {$tag1->name}\n";
    echo "- 添加标签: {$tag2->name}\n";
    echo "- 添加标签: {$tag3->name}\n";
    
    // 模拟获取文章的所有标签
    echo "\n文章《{$post->title}》的标签:\n";
    echo "- {$tag1->name}\n";
    echo "- {$tag2->name}\n";
    echo "- {$tag3->name}\n";
} catch (\Exception $e) {
    echo "模型关系示例失败: " . $e->getMessage() . "\n";
}

// 示例5：模型属性转换和访问器/修改器
echo "\n示例5：模型属性转换和访问器/修改器\n";
echo "--------------------------------------\n";

try {
    $user = new User([
        'name' => '属性测试用户',
        'email' => 'attribute@example.com',
        'password' => 'attribute123' // 会通过修改器进行哈希处理
    ]);
    
    echo "用户密码已通过修改器进行哈希处理\n";
    echo "原始密码: attribute123\n";
    echo "哈希后: {$user->password}\n";
    
    // 验证密码
    $isValid = $user->verifyPassword('attribute123');
    echo "密码验证 " . ($isValid ? '成功' : '失败') . "\n";
    
    // 测试属性类型转换
    $post = new Post([
        'title' => '属性转换测试',
        'content' => '测试内容',
        'created_at' => '2023-01-01 10:00:00'
    ]);
    
    echo "\n日期属性转换:\n";
    echo "原始值: 2023-01-01 10:00:00\n";
    echo "转换后: {$post->created_at}\n";
    
    // 测试属性序列化（隐藏敏感字段）
    echo "\n属性序列化（隐藏敏感字段）:\n";
    echo json_encode($user->toArray(), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
    echo "注意：密码字段已被隐藏\n";
} catch (\Exception $e) {
    echo "属性转换示例失败: " . $e->getMessage() . "\n";
}

echo "\n高级示例运行完成\n";